%include "syscalls.asm"
%include "print_type.asm"
%include "heap.asm"
%include "type_check.asm"

section	.text

bltn_cons:
	;; INPUT: rax, r8
	;; output: (cons rax r8) in the rax register
	
	;; save rax
	;; [ASSUMPTION: heap_alloc does not trash r9]
	mov	r9, rax
	
	;; allocate heap space
	mov	rax, 2
	call	heap_alloc
	
	;; put the CAR in
	mov	[rax], r9
	
	;; put the CDR in
	mov	[rax + 8], r8

	;; create a cons cell object to return
	or	rax, 0b010
	
	ret

bltn_car:
	;; INPUT:  rax
	;; OUTPUT: car(rax)
	
	;; ensure that it is a cons
	mov	r8, 0b010
	call	type_check
	
	;; extract the pointer
	mov	rcx, rax
	and	rcx, 0xFFFFFFFFFFFFFFFC
	
	;; deref it
	mov	rax, [rcx]
	
	ret

bltn_cdr:
	;; INPUT:  rax
	;; OUTPUT: cdr(rax)
	
	;; ensure that it is a cons
	mov	r8, 0b010
	call	type_check
	
	;; extract the pointer
	mov	rcx, rax
	and	rcx, 0xFFFFFFFFFFFFFFFC
	
	;; inc
	add	rcx, 8
	
	;; deref it
	mov	rax, [rcx]
	
	ret
